package com.speedchina.permission.service.sys;

import com.speedchina.framework.base.IService;
import com.speedchina.permission.domain.sys.dto.ResourceDTO;
import com.speedchina.permission.domain.sys.entity.User;
import com.speedchina.permission.domain.sys.po.UserPo;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.io.Serializable;
import java.util.List;

/**
 * 系统-用户表 服务层接口
 * @author hank
 * @date 2021-04-08 13:59:05
 */
public interface UserService extends IService<User> {
    /**
     * 修改密码（适用于 用户自己改密码，或管理员帮助改密码/重置，或基于邮件发送密码重置链接场景 在 controller 处理好关系即可）
     * 该方法内部只处理用户、老密码是否匹配，若匹配则更为新密码（密码规则校验或可单独使用插件实现）
     * 逻辑规则：老密码 加盐比较 库，新密码 重设置 盐 再加密存储
     * @param userId 待修改者ID （）
     * @param oldPwd 明文密码（前后端传输时所有密码都是加密传输，到 controller 解析）
     * @param newPwd
     * @return
     */
    boolean changePassword(String userId, String oldPwd, String newPwd);

    /**
     * 保存 用户信息
     * 1、<del>校验 用户名 是否重复（数据库做唯一约束，针对那种用户名一样只是通过状态判断的要求 不考虑）</del>
     * 2、依次执行：保存用户信息（注意密码初始化/前端匹配）、保存用户-角色关系、保存用户-独立资源关系
     * 3、若属于初始化 但不是固定值，则需要约束邮箱/短信等手段，将密码发给用户
     * @param userPo
     * @return
     */
    UserPo save(UserPo userPo);

    /**
     * 修改 用户信息【不处理 password、用户名 】
     * 1、更新用户信息
     * 2、判断角色是否修改，若修改，则批量移除关系之后再重新维护关系表
     * 3、判断独立资源是否修改，若修改，则批量移除关系之后再重新维护关系表
     * @param userPo
     * @return
     */
    boolean update(UserPo userPo);

    /**
     * 删除用户关联的资源信息与角色信息
     * @param ids
     * @param currentUser
     * @return
     */
    boolean deleteUserAndLinked(List<Serializable> ids, User currentUser);

    /**
     * 查询用户菜单树
     * @param userPo
     * @return
     */
    List<ResourceDTO> queryUserMenuTree(User userPo);

    /**
     * 根据用户名查询用户
     * @param username
     * @return
     */
    User getByUserName(String username);

    User getByUserPhone(String tel);
    /**
     * 管理员重置用户密码使用
     * @param id
     * @param newPwd
     * @return
     */
    boolean resetUserPassword(String id, String newPwd);

    /**
     * 重置用户密码(自助重置)
     * @param id
     * @param newPassword
     * @param salt
     * @return
     */
    boolean resetUserPassword(String id, String newPassword, String salt);

    boolean resetUserPasswordOauth2(String id, String newPassword);
}
